﻿#region Using Statements
using Microsoft.Xna.Framework;
#endregion

namespace DirectZZT.Shared.Screens
{
    /// <summary>
    /// Screen base class.
    /// </summary>
    public abstract class ScreenBase : IScreen
    {
        #region Properties

        /// <summary>
        /// Gets/sets the <see cref="IScreenManager"/> to which this screen is attached to.
        /// </summary>
        protected IScreenManager ScreenManager { get; set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the Screen class.
        /// </summary>
        public ScreenBase()
        {
            this.ScreenResult = Screens.ScreenResult.Stay;
            this.Opacity = 1.0f;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Returns the absolute coordinate from a percentual x value.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        protected float GetX(float x)
        {
            return (float)((x * this.ScreenManager.Game.GraphicsDevice.Viewport.Width) / 100f);
        }

        /// <summary>
        /// Returns the absolute coordinate from a percentual y value.
        /// </summary>
        /// <param name="y"></param>
        /// <returns></returns>
        protected float GetY(float y)
        {
            return (float)((y * this.ScreenManager.Game.GraphicsDevice.Viewport.Height) / 100f);
        }

        #endregion

        #region IScreen Members

        /// <summary>
        /// Gets the result of the screen (for the screen manager).
        /// This one is evaluated each cycle and determines whether the screen stays or leaves.
        /// </summary>
        /// <remarks>Setting only allowed by derived classes.</remarks>
        public ScreenResult ScreenResult { get; set; }
        /// <summary>
        /// Gets/sets the opacity level of this screen.
        /// 1.0f is opaque (non-transparent) and 0.0f is transparent. The default value is 1.0f.
        /// </summary>
        public float Opacity { get; set; }
        /// <summary>
        /// Gets/sets whether or not this screen is currently active.
        /// </summary>
        public bool IsActive { get; set; }
        /// <summary>
        /// Gets/sets whether or not this <see cref="IScreen"/>-instance requires calls to
        /// <see cref="Update(double)"/> and <see cref="Draw()"/> even if it isn't active.
        /// </summary>
        public bool ForceProcessingWhileInactive { get; set; }
        
        /// <summary>
        /// Called when this screen is attached to a <see cref="IScreenManager"/>.
        /// </summary>
        /// <param name="screenManager"></param>
        public virtual void OnAttach(IScreenManager screenManager)
        {
            this.ScreenManager = screenManager;
        }

        /// <summary>
        /// Called when this screen is entered.
        /// </summary>
        public virtual void OnEnter()
        {
        }

        /// <summary>
        /// Called when this screen is left.
        /// </summary>
        public virtual void OnLeave()
        {
        }

        /// <summary>
        /// Updates this screen.
        /// </summary>
        /// <param name="gameTime"></param>
        public abstract void Update(GameTime gameTime);

        /// <summary>
        /// Draws this screen.
        /// </summary>
        /// <param name="gameTime"></param>
        public abstract void Draw(GameTime gameTime);

        #endregion
        
        #region IDisposable Members

        /// <summary>
        /// Releases any managed and unmanaged resources.
        /// </summary>
        public virtual void Dispose()
        {

        }

        #endregion
    }
}
